using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace Possan.Graphics.Filters
{
	/// <summary>
	/// Change contrast and/or brightess of an image
	/// </summary>
	public class Levels : IBaseFilter
	{
		public string ParameterDefinition
		{
			get
			{
				return null;
			}
		}


		int _InputRedMin;
		int _InputRedMax;
		int _InputGreenMin;
		int _InputGreenMax;
		int _InputBlueMin;
		int _InputBlueMax;
		int _InputAlphaMin;
		int _InputAlphaMax;

		int _OutputRedMin;
		int _OutputRedMax;
		int _OutputGreenMin;
		int _OutputGreenMax;
		int _OutputBlueMin;
		int _OutputBlueMax;
		int _OutputAlphaMin;
		int _OutputAlphaMax;




		public int InputRedMin
		{
			get { return _InputRedMin; }
			set { _InputRedMin = value; }
		}

		public int InputRedMax
		{
			get { return _InputRedMax; }
			set { _InputRedMax = value; }
		}

		public int InputGreenMin
		{
			get { return _InputGreenMin; }
			set { _InputGreenMin = value; }
		}

		public int InputGreenMax
		{
			get { return _InputGreenMax; }
			set { _InputGreenMax = value; }
		}

		public int InputBlueMin
		{
			get { return _InputBlueMin; }
			set { _InputBlueMin = value; }
		}

		public int InputBlueMax
		{
			get { return _InputBlueMax; }
			set { _InputBlueMax = value; }
		}

		public int InputAlphaMin
		{
			get { return _InputAlphaMin; }
			set { _InputAlphaMin = value; }
		}

		public int InputAlphaMax
		{
			get { return _InputAlphaMax; }
			set { _InputAlphaMax = value; }
		}


		public int OutputRedMin
		{
			get { return _OutputRedMin; }
			set { _OutputRedMin = value; }
		}

		public int OutputRedMax
		{
			get { return _OutputRedMax; }
			set { _OutputRedMax = value; }
		}

		public int OutputGreenMin
		{
			get { return _OutputGreenMin; }
			set { _OutputGreenMin = value; }
		}

		public int OutputGreenMax
		{
			get { return _OutputGreenMax; }
			set { _OutputGreenMax = value; }
		}

		public int OutputBlueMin
		{
			get { return _OutputBlueMin; }
			set { _OutputBlueMin = value; }
		}

		public int OutputBlueMax
		{
			get { return _OutputBlueMax; }
			set { _OutputBlueMax = value; }
		}

		public int OutputAlphaMin
		{
			get { return _OutputAlphaMin; }
			set { _OutputAlphaMin = value; }
		}

		public int OutputAlphaMax
		{
			get { return _OutputAlphaMax; }
			set { _OutputAlphaMax = value; }
		}

		public Levels()
		{
			InputRedMin = 0;
			InputRedMax = 255;

			InputGreenMin = 0;
			InputGreenMax = 255;

			InputBlueMin = 0;
			InputBlueMax = 255;

			InputAlphaMin = 0;
			InputAlphaMax = 255;

			OutputRedMin = 0;
			OutputRedMax = 255;

			OutputGreenMin = 0;
			OutputGreenMax = 255;

			OutputBlueMin = 0;
			OutputBlueMax = 255;

			OutputAlphaMin = 0;
			OutputAlphaMax = 255;
		}

		static int LERP(int input, int in0, int in1, int out0, int out1)
		{
			float tmp = (float)(input - in0) / (float)(in1 - in0);
			tmp = (tmp * (out1 - out0)) + out0;
			return (int)tmp;
		}

		public Bitmap Filter(Bitmap bmp)
		{
			Bitmap neu = Utilities.CloneBitmap(bmp);
			for (int j = 0; j < neu.Height; j++)
			{
				for (int i = 0; i < neu.Width; i++)
				{
					Color c = neu.GetPixel(i, j);
					Color c2 = Color.FromArgb(
						LERP(c.A, InputAlphaMin, InputAlphaMax, OutputAlphaMin, OutputAlphaMax),
						LERP(c.R, InputRedMin, InputRedMax, OutputRedMin, OutputRedMax),
						LERP(c.G, InputGreenMin, InputGreenMax, OutputGreenMin, OutputGreenMax),
						LERP(c.B, InputBlueMin, InputBlueMax, OutputBlueMin, OutputBlueMax));
					neu.SetPixel(i, j, c2);
				}
			}

			return neu;
		}

	}

}





